<?php
/**
  * Musashi - A project manager for music groups and bands
  * Copyright (C) 2010 Daniel Torres
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */

/**
 *  Controls sql operations over the Songs table of our database
 *
 *  @author Daniel Torres
 *  @package Musashi
 */

// Make sure we have access to this page
defined('_JEXEC') or die ('Restricted access. Sorry');

// Import the file utilities
jimport('joomla.filesystem.file');

/**
 *  Table definition. Reflects the Song table
 */
class TableSongs extends JTable
{
    /**
     *  Parameters handled by the actual table
     */
    var $id             = null;
    var $name           = null;
    var $description    = null;
    var $length         = null;
    var $sheet          = null;
    
    /**
     *  Constructor
     *  All the Musashi table constructors will be similar, except for the table name
     */
    function __construct( &$db )
    {
        parent::__construct('#__Musashi_Song', 'id', $db);
    }
    
    
    /**
     *  Binds the information into our database.
     *  Catches the name of the requested sheet, and uploads the actual file as necessary
     */
    function bind( $from )
    {

        // If a new sheet was requested, make sure it gets set
        $file = JRequest::getVar('newsheet', null, 'files', 'array');
        if( $file == null ){
            $file = JRequest::getVar('sheet', null, 'files', 'array');
        }
        
        // Make sure the sheet is uploaded
        $this->_updateSheet($file);
        
        // Perform the bind
        return parent::bind($from);
    }
    
    /**
     *  Stores the information into the database. Manages the songs_position
     *  and song_equipment operations
     */
    function store( $updateNulls = false )
    {
        // Perform conventional storing first
        if( parent::store($updateNulls) )
        {
            // Obtain the id of the recently stored song
            $lastID = $this->_getLastID();
            
            // Update the songs_positions table
            $sucess = $this->_updateDependantTable( $lastID, 'posid', '#__Musashi_Song_Position', 'idSong', 'idPosition' );
            
            return $sucess;            
        }
        else
        {
            return false;
        }
    }
    
    /**
     *  Deletes this record
     */
    function delete( $oid = null )
    {
        // Make sure anything pointing to this record is deleted
        $this->_removeRecordsFromTable( '#__Musashi_Song_Position', 'idSong', $oid );
        $this->_removeRecordsFromTable( '#__Musashi_Song_Equipment','idSong', $oid );
        
        // Proceed
        return parent::delete($oid);
    }
    
    /**
     *  Updates the records of a dependant table
     *  @param a_songID     ID of the song we are modifying    
     *  @param a_postID     ID of the expected parameter on the POST variable array
     *  @param a_tableName  The name of the dependant table
     *  @param a_keyName    Name of the key record
     *  @param a_foreignKey Name of the key we are inserting (the one that comes from the POST array)
     */
    function _updateDependantTable( $a_songID, $a_postID, $a_tableName, $a_keyName, $a_foreignKey )
    {        
        // See if we can remove the old records
        if( $this->_removeRecordsFromTable( $a_tableName, $a_keyName, $a_songID ) == false )
        {
            $app =& JFactory::getApplication();
            $app->enqueueMessage('Warning: Failed to update a database. Seek help. Table: '.$a_tableName);
        }
        
        // Unpack the list of keys
        $packedData = $_POST[$a_postID];
        
        // Proceed only if we have values. If we don't we would have sucessfully
        // removed the previous entries of the table
        if( $packedData == "" ){
            return true;
        }

        $unpacked = explode(",", $packedData);
        $count    = count($unpacked);
                                
        // Create an sql statement to insert the new values
        $query = "INSERT INTO ".$a_tableName." (".$a_foreignKey.",".$a_keyName.") ";
        $start = false;
        $id    = strval($a_songID);
        
        for( $i = 0; $i < $count; $i++ )
        {
            if( $start ){
                $query .= " UNION ALL ";
            }
                
            $query .= "SELECT ".strval($unpacked[$i]).",".$id;
            $start = true;
        }

        // Insert
        $db =& JFactory::getDBO();
        $db->setQuery( $query );
        if( $db->query() == false )
        {
            $app = &JFactory::getApplication();
            $app->enqueueMessage("Failed to update the song selection. Error: ".$db->explain());
            return false;
        }
            
        return true;            
    }
    
    /**
     *  Removes records from a given table, based on the provided IDs
     *  @param a_tableName     The name of the table to remove records from
     *  @param a_keyName       Name of the key record
     *  @param a_keyValue      Value of the rows to remove
     */
    function _removeRecordsFromTable( $a_tableName, $a_keyName, $a_keyValue )
    {
        // Create query
        $sql = "DELETE FROM ".$a_tableName." WHERE ".$a_tableName.".".$a_keyName." = ".$a_keyValue;
                
        // Actuate
        $db =& JFactory::getDBO();
        $db->setQuery( $sql );
        return $db->query();
        
    }
    
    /**
     *  Returns the right ID for the last added/edited record
     */
    function _getLastID()
    {
        // Either the one stored on the page, or the recently added
        $stored = $_POST['id'];
        
        if( $stored == "" ){
            return mysql_insert_id();
        }
        
        return $stored;
    }
    
    
    
    /**
     *  Uploads a sheet for this song, if requested.
     */
    function _updateSheet( $file )
    {
        if( $file != null)
        {
            // Clean the filename. Make sure one was specified.
            $filename = JFile::makeSafe($file['name']);
            
            if( $filename == "" ){
                return;
            }
            
            // We'll need this:
            $app = &JFactory::getApplication();
            
            // Make sure the filename has no more than 55 characters (db limitation)
            if( strlen($filename) >= 50 ){
                $app->enqueueMessage("Failed to load sheet file: Name cannot be bigger than 50 characters!", 'error');
                return;
            }
            
            $this->sheet = $filename;
            
            // Source, destination
            $src = $file['tmp_name'];
            $dst = JPATH_COMPONENT.DS."uploads".DS."sheets".DS.$filename;
            
            // See if we can upload the file
            if( JFile::upload($src,$dst) )
            {
                $app->enqueueMessage("Sucessfully loaded sheet file: ".$filename, 'message');
            }
            else
            {
                $app->enqueueMessage("Failed to load sheet file: ".$filename, 'error');                
            }
        }        
    }
    
    
}

?>